import argparse
import datetime
import random
import time
import threading
import subprocess
from concurrent.futures import ThreadPoolExecutor

from TrafficGenerator.traffic_configuration import TrafficConfiguration
from TrafficGenerator.traceroute_utils import estimate_initial_ttl_values_from_pcap

default_output_file_name = 'log.pcap'
default_histogram_file_name = 'log_ttl_hist.txt'

def request_thread(request):
    try:
        print('{0} {1}: Requesting {2}'.format(datetime.datetime.now(),threading.currentThread().ident, request[1]))
        request[0](request[1])
    except Exception:
        pass


def main(seconds, hist):
    beginning = datetime.datetime.now()
    # Start recording
    p = subprocess.Popen('windump -s 0 -i 1 -w {0} tcp and dst port not 80 and dst port not 443'.format(default_output_file_name))

    try:
        with ThreadPoolExecutor(max_workers=TrafficConfiguration.NUMBER_OF_THREADS) as executor:
            while True:
                now = datetime.datetime.now()
                if (now - beginning).total_seconds() > int(seconds):
                    return
                number_of_requests = int(TrafficConfiguration.REQUESTS_DISTRIBUTION(*TrafficConfiguration.REQUESTS_DISTRIBUTION_PARAMS))
                for _ in range(number_of_requests):
                    request = random.choice(TrafficConfiguration.DESTINATIONS)
                    executor.submit(request_thread, request)
                sleep_time = max(0, int(TrafficConfiguration.SLEEP_DISTRIBUTION(*TrafficConfiguration.SLEEP_DISTRIBUTION_PARAMS)))
                print('Sleeping for {0} seconds'.format(sleep_time))
                time.sleep(sleep_time)
    finally:
        p.kill()

        if hist is not None:
            ttl_histogram = estimate_initial_ttl_values_from_pcap(default_output_file_name)
            number_of_packets = sum(dict(ttl_histogram).values())
            with open(hist,'w') as hist_file:
                for key, value in ttl_histogram:
                    hist_file.write('%d: %d (%.2f%%)\r\n'%(key, value, value / number_of_packets,))
                hist_file.write('Total of {0} ips tracerouted'.format(number_of_packets))


if (__name__ == "__main__"):
    parser = argparse.ArgumentParser()
    parser.add_argument("seconds",)
    parser.add_argument("--hist",)
    args = parser.parse_args()
    main(**vars(args))